package org.dreamwork.jasmine2.restful;

import com.google.gson.annotations.Expose;
import org.dreamwork.secure.SecureContext;
import org.dreamwork.util.IDisposable;

import javax.servlet.ServletContext;
import java.util.HashMap;
import java.util.Map;
import java.util.WeakHashMap;

/**
 * Created with IntelliJ IDEA.
 * User: seth.yang
 * Date: 14-11-17
 * Time: 下午5:23
 */
public class RestfulAPIContext implements IDisposable {
    static Map<String, ContextParameterDefinition> parameters = new HashMap<String, ContextParameterDefinition> ();
    static String description, title;
    static ThreadLocal<RestfulAPIContext> pool = new ThreadLocal<> ();
    static SecureContext secureContext;
    static Boolean appIdRequired;
    static AppIdLocation location;

    @Expose
    Map<String, Object> map = new HashMap<> ();

    private Map<String, Object> extras = new WeakHashMap<> ();

    String mapping, version, client;
    ServletContext application;
    boolean encrypted = false;

    RestfulAPIContext () {
        pool.set (this);
    }

    public static RestfulAPIContext getCurrentContext () {
        return pool.get ();
    }

    @SuppressWarnings ("unchecked")
    public <T> T get (String key) {
        return (T) map.get (key);
    }

    @SuppressWarnings ("unchecked")
    public <T> T get (String key, T defaultValue) {
        if (map.containsKey (key))
            return (T) map.get (key);
        return defaultValue;
    }

    void set (String key, Object value) {
        map.put (key, value);
    }

    public boolean contains (String key) {
        return map.containsKey (key);
    }

    static void addContextParameterName (ContextParameterDefinition parameter) {
        parameters.put (parameter.getName (), parameter);
    }

    static boolean isRequiredContextParameter (String name) {
        return parameters.containsKey (name) && parameters.get (name).isRequired ();
    }

    static boolean isContextParameter (String name) {
        return parameters.containsKey (name);
    }

    public static String getDescription () {
        return description;
    }

    public static String getTitle () {
        return title;
    }

    void setMapping (String mapping) {
        this.mapping = mapping;
    }

    public String getMapping () {
        return mapping;
    }

    void setApplication (ServletContext application) {
        this.application = application;
    }

    public ServletContext getApplication () {
        return application;
    }

    @Override
    public String toString () {
        return map.toString ();
    }

    @Override
    public void dispose () {
        try {
            map.clear ();
            extras.clear ();
        } finally {
            pool.remove ();
        }
    }

    public SecureContext getSecureContext () {
        return secureContext;
    }

    public void putExtra (String name, Object value) {
        extras.put (name, value);
    }

    @SuppressWarnings ("unchecked")
    public<T> T getExtra (String name) {
        return (T) extras.get (name);
    }
}